package com.vhall.component.controller.reward;

import com.vhall.component.controller.reward.facade.RewardFacade;
import com.vhall.component.controller.room.facade.RoomInnerFacade;
import com.vhall.component.entity.reward.dto.RewardGiveDTO;
import com.vhall.component.entity.reward.vo.*;
import com.vhall.component.entity.room.dto.RoomJoinsEntityDTO;
import com.vhall.component.entity.room.dto.RoomsEntityDTO;
import com.vhall.component.framework.common.annotation.VhallComponent;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.annotation.VssTokenAuth;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.common.support.VssToken;
import com.vhall.component.plugin.common.support.VssTokenThreadLocal;
import com.vhall.component.service.reward.RewardService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author lsl
 * @since 2021/7/6
 */
@VhallComponent
public class RewardController implements RewardFacade {

    @Autowired
    private RoomInnerFacade roomInnerFacade;

    @Autowired
    private RewardService rewardService;

    /**
     * 金额正则判断
     */
    private static final Pattern AMOUNT = Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$");


    /**
     * 进行打赏
     *
     * @param reqVO
     * @return
     */
    @Override
    @VssTokenAuth
    public RewardGiveRspVO give(RewardGiveReqVO reqVO) {
        VssToken token = VssTokenThreadLocal.getToken();

        Integer thirdUserId = token.getThirdPartyUserId();
        // 验证房间是否存在
        RoomsEntityDTO roomInfo = checkRoom(reqVO.getRoomId());
        // 验证用户是否正确
        RoomJoinsEntityDTO userInfo = checkUser(reqVO.getRoomId(), thirdUserId);

        // 验证service_code为JSAPI时，openId是否为空
        checkOpenId(reqVO.getServiceCode(), reqVO.getOpenId());

        // 验证金额是否小于0
        checkAmount(reqVO.getRewardAmount());

        RewardGiveDTO rewardGiveDTO = new RewardGiveDTO();
        BeanUtils.copyProperties(reqVO, rewardGiveDTO);
        rewardGiveDTO.setRewarderId(String.valueOf(thirdUserId));
        if (StringUtils.isNotBlank(userInfo.getNickname())) {
            rewardGiveDTO.setRewarderNickname(userInfo.getNickname());
        }
        if (StringUtils.isNotBlank(userInfo.getAvatar())) {
            rewardGiveDTO.setRewarderAvatar(userInfo.getAvatar());
        }
        if (StringUtils.isBlank(reqVO.getDescribe())) {
            rewardGiveDTO.setDescribe("很精彩，赞一个！");
        }
        rewardGiveDTO.setReceiverId(roomInfo.getAccountId() != null ? roomInfo.getAccountId().toString() : "");

        return rewardService.give(rewardGiveDTO);


    }

    @Override
    @VssTokenAuth
    public RewardRankRspVO rewarderRank(RewardRankReqVO reqVO) {
        VssToken token = VssTokenThreadLocal.getToken();

        Integer thirdUserId = token.getThirdPartyUserId();
        // 验证房间是否存在
        checkRoom(reqVO.getRoomId());
        // 验证用户是否正确
        RoomJoinsEntityDTO userInfo = checkUser(reqVO.getRoomId(), thirdUserId);
        return rewardService.rewarderRank(reqVO, userInfo);
    }

    @Override
    @VssTokenAuth
    public RewardRankListRspVO rewardListRank(RewardListRankReqVO reqVO) {
        VssToken token = VssTokenThreadLocal.getToken();
        Integer thirdUserId = token.getThirdPartyUserId();
        // 验证房间是否存在
        checkRoom(reqVO.getRoomId());
        // 验证用户是否正确
        checkUser(reqVO.getRoomId(), thirdUserId);

        if (reqVO.getOffset() == null) {
            reqVO.setOffset(0);
        }
        if (reqVO.getLimit() == null) {
            reqVO.setLimit(10);
        }
        if (StringUtils.isBlank(reqVO.getSortType())) {
            reqVO.setSortType("desc");
        }
        return rewardService.rewardlistRank(reqVO);
    }

    @Override
    @VssTokenAuth
    public RewardRecordsRspVO rewardRecordsList(RewardRecordsListReqVO reqVO) {
        VssToken token = VssTokenThreadLocal.getToken();

        Integer thirdUserId = token.getThirdPartyUserId();
        // 验证房间是否存在
        checkRoom(reqVO.getRoomId());
        // 验证用户是否正确
        checkUser(reqVO.getRoomId(), thirdUserId);
        if (reqVO.getOffset() == null) {
            reqVO.setOffset(0);
        }
        if (reqVO.getLimit() == null) {
            reqVO.setLimit(10);
        }
        return rewardService.rewardRecordsList(reqVO);
    }

    private void checkAmount(BigDecimal rewardAmount) {
        Matcher match = AMOUNT.matcher(String.valueOf(rewardAmount));
        if (!match.matches()) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }
    }

    private void checkOpenId(String serviceCode, String openId) {
        //0. 联合参数校验
        if (Objects.equals("JSAPI", serviceCode) && StringUtils.isBlank(openId)) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }
    }

    private RoomsEntityDTO checkRoom(String roomId) {
        RoomsEntityDTO roomInfo = roomInnerFacade.getRoomInfo(roomId);
        if (roomInfo == null) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }
        return roomInfo;
    }

    private RoomJoinsEntityDTO checkUser(String roomId, Integer thirdId) {
        RoomJoinsEntityDTO userInfo = roomInnerFacade.getRoomJoinInfo(thirdId, roomId);
        if (userInfo == null) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_USER);
        }
        return userInfo;
    }
}
